java类的“set”方法是否应该返回“void”或“boolean”?
所以我在设计一个类的时候经常遇到这个问题:
class foo {
private Bar bar;
public foo(Bar bar) {
this.bar = bar;
}
public Bar getBar() {
return bar;
}
public void setBar(Bar bar) {
this.bar = bar;
}
}
到目前为止还不错,对吧?但是我想“我怎么知道用户会传递一个可接受的bar
对象呢
private bool validateBar(Bar bar) {
return amIgood(bar);
}
当然,我需要把它和setBar
函数放在一起,如下所示:
public bool setBar(Bar bar) {
if (validateBar(bar)) {
this.bar = bar;
return true;
}
else
return false;
}
如果这就是我需要做的,那么我也必须包含在构造函数中,对吗?除了构造函数没有返回foo
对象以外的任何对象的选项,所以我尝试并考虑解决方法,如下所示:
public foo(Bar bar) {
if validateBar(bar)
this.bar = bar;
else
throw Exception("Invalid bar passed along to foo");
}
或:
public foo(Bar bar) {
if (!setBar(bar))
throw Exception("Invalid bar passed along to foo");
}
你可以看到一些简单的事情是如何很快失去控制的。如果在验证的基础上还要做一些卫生工作,那就更糟糕了
所以我的问题是,如何在保持类结构相对简单的同时处理验证问题
编辑
setbar
的第一个例子应该是void
,但意外地放了bar
,现在更正了
# 1 楼答案
以上都没有
按照惯例,如果实现fluent interface,setter返回
void
,但可能返回实例的类型(在本例中为Foo
,而不是Bar
),在这种情况下,setter方法的最后一行是return this;
。(您的示例缺少返回,因此无法编译)如果setter的参数必须为“valid”,则不应影响返回类型。相反,该方法应该爆炸:
这里不返回布尔值的一个很好的理由是,调用方可能不会检查返回值,并且可能会盲目地继续,好像一切正常,这当然是不好的
此外,最好通过在
Bar
构造函数中移动validateBar()
的逻辑,抛出一个IllegalArgumentException
来避免创建无效的Bar
,如果传入的参数将创建一个无效的Bar
,那么可以从Foo
中删除检查如果
validateBar()
方法是static
,这意味着可以在没有Foo
上下文的情况下验证Bar
,因此逻辑应该在Bar
-Foo
中实现,如果不需要验证Bar
,则它不应该负责或知道如何验证但是,如果
Foo
对一个有效的Bar
有特殊的要求,而这个要求不适用于其他地方,那么创建一个Bar
的子类,例如FooBar extends Bar
,它同样在其构造函数中实现了Foo
的特殊验证要求如果验证一个
Bar
确实需要一个Foo
的上下文来验证,并且在Foo
之间重用Bar
实例是不需要的,那么Bar
类应该是Foo
的一个内部类,在这种情况下,验证仍然可以在条中constructor, and the state of the containing
Foo`可根据需要用于验证逻辑如果验证一个
Bar
需要一个Foo
的上下文来验证,和需要重用Bar
实例,那么Bar
不能是一个内部类,验证代码应该存在于Foo
中,正如您在validateBar(Bar bar)
方法中所建议的那样,除非它不是static
,否则该方法将使用Foo
字段也考虑重新命名它^ {CD38>},因为参数的类型使被验证的内容变得清晰。